#import "textundo.h"

@implementation TextSelChange

/*
 * The TextSelChange is the workhorse of undoable text. It records the
 * contents of the selection (via TextSelection objects) before and after
 * a change is made. By alternately installing and removing the old and new
 * selections, the original change can be undone and redone.
 */

- initView:aView name:(const char *)str
{
    [super initView:aView];

    oldSel = nil;
    newSel = nil;

    name = str;

    return self;
}

- free
{
    if (newSel) {
	[newSel free];
    }

    if (oldSel) {
	[oldSel free];
    }

    return [super free];
}

- (const char *)changeName
{
    return name;
}

- saveAfterChange
{
    newSel = [[[TextSelection alloc] initText:textView] capture];
    return self;
}

- saveBeforeChange
{
    NXSelPt start, end;

    [textView getSel:&start :&end];
    selStart = start.cp;
    selEnd = end.cp;

    oldSel = [TextSelection alloc];
    [[oldSel initText:textView start:selStart end:selEnd] capture];
    [oldSel setClickCount:[newSel clickCount]];

    return self;
}

- undoChange
{
    [[textView window] disableFlushWindow];
    [newSel remove];
    [oldSel install];
    [[[textView window] reenableFlushWindow] flushWindow];
    
    return [super undoChange];
}

- redoChange
{
    NXRect oldBounds, invalidRect;
    id delegate;

    [[textView window] disableFlushWindow];

    if (delegate = [textView delegate]) {
	[textView getBounds:&oldBounds];
	invalidRect = oldBounds;
	invalidRect.size.width = 0.0;
	invalidRect.size.height = 0.0;
    } else {
	delegate = nil;
    }

    [oldSel remove];
    [newSel install];

    if (delegate != nil &&
       [delegate respondsTo:@selector(textDidResize:oldBounds:invalid:)])
    {
	[delegate textDidResize:textView
                      oldBounds:&oldBounds
                        invalid:&invalidRect];
    }

    [[[textView window] reenableFlushWindow] flushWindow];

    return [super redoChange];
}

@end
